<template>
  <!-- demo1 -->
  <div
    class="home"
    id="container"
  >
    <h1>拖动窗口自适应大小</h1>
    <el-button
      type="primary"
      @click="changeDemo"
    >demo2</el-button>
  </div>
</template>

<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import G6 from '@antv/g6';

// 路由
const router = useRouter();
// 模拟数据
const data = {
  nodes: [
    {
      id: '10.0.0.1', // String，该节点存在则必须，节点的唯一标识
      label: '节点1',
    },
    {
      id: '192.168.1.1',
      label: '节点2',
    },
    {
      id: '192.168.1.2',
      label: '节点3',
    },
    {
      id: '10.0.0.2',
      label: '节点4',
    },
  ],
  edges: [
    {
      source: '10.0.0.1', // String，必须，起始点 id
      target: '192.168.1.1', // String，必须，目标点 id
      label: '节点1->节点2',
    },
    {
      source: '10.0.0.1',
      target: '192.168.1.1',
      label: '节点1->节点2',
    },
    {
      source: '192.168.1.1',
      target: '10.0.0.1',
      label: '节点2->节点1',
    },
    {
      source: '192.168.1.1',
      target: '192.168.1.2',
      label: '节点2->节点3',
    },
    {
      source: '192.168.1.2',
      target: '192.168.1.2',
      label: '节点3->节点3',
    },
    {
      source: '192.168.1.2',
      target: '10.0.0.2',
      label: '节点3->节点4',
    },
    {
      source: '10.0.0.2',
      target: '192.168.1.2',
      label: '节点4->节点3',
    },
    {
      source: '10.0.0.2',
      target: '10.0.0.1',
      label: '节点4->节点1',
    },
  ],
};
// 图谱实例化对象
const graph = ref(null);
/* 挂载钩子 */
onMounted(() => {
  initGraph();
});
/* 卸载钩子 */
onUnmounted(() => {
  if (graph.value) {
    // 清空数据（可省略）
    graph.value.clear();
    // 销毁画布
    graph.value.destroy();
    // 将画布实例对象置空
    graph.value = null;
  }
});
/* 切换demo */
const changeDemo = () => {
  router.push('/index');
};
/* 初始化图谱 */
const initGraph = () => {
  // 节点添加提示框
  const tooltip = new G6.Tooltip({
    offsetX: 10, // tooltip 的 x 方向偏移值，需要考虑父级容器的 padding
    offsetY: 20, // tooltip 的 y 方向偏移值，需要考虑父级容器的 padding
    getContent(e) {
      const outDiv = document.createElement('div');
      outDiv.style.width = '180px';
      outDiv.innerHTML = `
          <ul>
            <li>节点IP：${e.item.getModel().id}</li>
          </ul>`;
      return outDiv;
    },
    itemTypes: ['node'] // 给node添加tooltip
  });
  graph.value = new G6.Graph({
    container: 'container', // String | HTMLElement，必须，容器 id 或容器本身
    width: document.getElementById('container').clientWidth, // Number，必须，图的宽度
    height: document.getElementById('container').clientHeight, // Number，必须，图的高度
    fitCenter: true, // 是否平移图使其中心对齐到画布中心
    plugins: [tooltip], // 添加tooltip
    // 画布配置
    modes: {
      default: ['drag-canvas', 'zoom-canvas', 'drag-node'], // 允许拖拽画布、放缩画布、拖拽节点
    },
    // 基本配置
    layout: {
      type: 'force', // 指定为力导向布局
      preventOverlap: true, // 防止节点重叠
      linkDistance: 180, // 指定边距离为150
      nodeSpacing: 85, // 防止重叠时节点边缘间距的最小值
      alpha: 1, // 当前的迭代收敛阈值
      alphaDecay: 0.05, // 迭代阈值的衰减率。范围 [0, 1]
    },
    // 默认节点配置
    defaultNode: {
      type: 'rect', // 节点类型
      size: [120, 46],
      style: {
        fill: '#F6FCFE', // 填充色
        stroke: '#2EA1FF', // 节点描边颜色
        shadowColor: 'rgba(78,89,105,0.3)', // 阴影颜色
        lineWidth: 1, // 描边宽度
        radius: 3, // 圆角
        shadowBlur: 2, // 阴影大小
      },
      // 文本配置
      labelCfg: {
        position: 'center',
        style: {
          fontSize: 14,
          fill: '#0282FF',
          fontWeight: 400,
        },
      },
    },
    // 默认边配置
    defaultEdge: {
      type: 'loop', // 设置边默认为“自环”类型
      style: {
        stroke: '#2EA1FF',
        lineWidth: 1,
        // 边添加箭头
        endArrow: {
          path: G6.Arrow.triangle(4, 4, 2),
          d: 2,
          fill: '#2EA1FF',
        }
      },
      labelCfg: {
        autoRotate: true,
        refY: 12,
        style: {
          fontSize: 12,
          fill: '#1D2129',
        }
      },
    },
    // 边状态样式
    edgeStateStyles: {
      selected: {
        stroke: '#0282FF',
        shadowBlur: 0,
        'text-shape': {
          fill: "#0282FF",
          fontWeight: 600,
        }
      }
    },
    // 节点状态样式
    nodeStateStyles: {
      // 选中后样式
      selected: {
        fill: '#0282FF', // 填充色
        stroke: '#0282FF', // 节点描边颜色
        lineWidth: 1, // 描边宽度
        shadowColor: 'rgba(0,102,210,0.5)',
        'text-shape': {
          fill: "#ffffff"
        }
      },
      // 悬浮后样式
      active: {
        fill: '#CDEEFF', // 填充色
        stroke: '#2EA1FF', // 节点描边颜色
        lineWidth: 1, // 描边宽度
        shadowColor: 'rgba(78,89,105,0.3)',
        'text-shape': {
          fill: "#0282FF",
          fontWeight: 500,
        }
      }
    }
  });
  // 添加节点间多条连线，贝塞尔曲线
  G6.Util.processParallelEdges(data.edges, 65);
  // 解决拖动产生残影问题
  graph.value.get('canvas').set('localRefresh', false);
  // 边添加点击事件
  graph.value.on('edge:click', (evt) => {
    const { item } = evt;
    graph.value.getEdges().forEach((edge) => {
      graph.value.clearItemStates(edge);
    });
    graph.value.getNodes().forEach((node) => {
      graph.value.clearItemStates(node);
    });
    graph.value.setItemState(item, 'selected', true);
    // 高亮关联节点
    graph.value.setItemState(item['_cfg'].source, 'selected', true);
    graph.value.setItemState(item['_cfg'].target, 'selected', true);
  });
  // 节点悬浮高亮
  graph.value.on('node:mouseover', (e) => {
    graph.value.setItemState(e.item, 'active', true);
  });
  // 节点鼠标移出后使tooltip消失并取消节点悬浮高亮
  graph.value.on('node:mouseout', (e) => {
    document.getElementsByClassName('g6-component-tooltip')[0].style.display = 'none';
    graph.value.setItemState(e.item, 'active', false);
  });
  graph.value.data(data);
  graph.value.render();
  window.addEventListener('resize', () => {
    //graph.value.changeSize(document.getElementById('container').clientWidth, document.getElementById('container').clientHeight);
    graph.value.fitCenter();
  });
}
</script>

<style lang="less" scoped>
.home {
  width: 100%;
  height: 100%;
  position: relative;
  h1 {
    position: absolute;
  }
  .el-button {
    position: absolute;
    top: 50px;
  }
}
</style>
<style lang="less">
.g6-component-tooltip {
  background-color: rgba(0, 0, 0, 0.7);
  padding: 7px 17px;
  box-shadow: none;
}
.g6-component-tooltip ul li {
  font-size: 12px;
  font-weight: 400;
  color: #ffffff;
  line-height: 19px;
}
</style>